﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Timers;
using System.Windows;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using MediaPlayerSongReader.Exception;
using MediaPlayerSongReader.MediaPlayers;
using Microsoft.Win32;
using Button = System.Windows.Controls.Button;
using MediaPlayer = MediaPlayerSongReader.MediaPlayers.MediaPlayer;
using MessageBox = System.Windows.MessageBox;
using SaveFileDialog = System.Windows.Forms.SaveFileDialog;
using Timer = System.Timers.Timer;

namespace MediaPlayerSongReader
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private string[] _availableMediaPlayers;

        private bool _runningSpotify = false;
        private bool _runningWinAmp = false;
        private bool _runUpdateSongTimer = false;
        private MediaPlayer _selectedMediaPlayer = null;
        private readonly Timer _songTimer = new Timer { Interval = 250 };
        private readonly Timer _mediaPlayerTimer = new Timer { Interval = 200 };
        private string _lock = "MyLock";
        private string _path;

        private const double DefaultOpacity = 0.3;
        private readonly Color _defaultColor = Colors.Gray;


        private string _notFetchingMusic = "Not fetching music";
        private string _fetchingMusic = "Fetching music from:";

        private MediaPlayer SelectedMediaPlayer
        {
            get { return _selectedMediaPlayer; }
            set
            {
                lblSelectedMediaPlayer.Dispatcher.BeginInvoke(new Action(() => { lblSelectedMediaPlayer.Content = value == null ? _notFetchingMusic : _fetchingMusic + value.Name; }));
                _selectedMediaPlayer = value;
            }
        }

        private string Path { 
            get { return _path; } 
            set
            {
                lblPath.Dispatcher.BeginInvoke(new Action(() => { lblPath.Content = value.Trim() == "" ? "Not set" : value; }));
                _path = value;
            } 
        }
        public MainWindow()
        {
            _availableMediaPlayers = new string[] { "spotify", "winamp" };
            InitializeComponent();
            Init( );
            Loaded += MainWindowLoaded;
            Closing += MainWindowClosing;
            
            _songTimer.Elapsed += SongTimerElapsed;
            _mediaPlayerTimer.Elapsed += MediaPlayerTimerElapsed;
            miAbout.Click += miAbout_Click;
            miChangeFile.Click += miChangeFile_Click;
            miOptions.Click += miOptions_Click;
            lblSelectedMediaPlayer.Content = _notFetchingMusic;

        }

        private void Init()
        {
            btnSpotify.OpacityMask = new SolidColorBrush( _defaultColor );
            btnWinamp.OpacityMask = new SolidColorBrush( _defaultColor );
            btnSpotify.Opacity = DefaultOpacity;
            btnWinamp.Opacity = DefaultOpacity;
        }

#region "Events"
        #region "Window events"

        private void MainWindowLoaded(object sender, RoutedEventArgs e)
        {

            //If a path has not been selected present the user with a folder selection window

            if ( Properties.Settings.Default.FilePath.Trim() == string.Empty )
            {
                SaveFileDialog fileDialog = new SaveFileDialog();

                if( fileDialog.ShowDialog( ) == System.Windows.Forms.DialogResult.OK )
                {
                    Properties.Settings.Default.FilePath = fileDialog.FileName;
                }
                else
                {
                    this.Close( );
                    return;
                }
            }

            Path = Properties.Settings.Default.FilePath;

            CheckForRunningMediaPlayers();
            btnSpotify.IsEnabled = _runningSpotify;
            btnWinamp.IsEnabled = _runningWinAmp;
            _mediaPlayerTimer.Start();
        }

        private void MainWindowClosing(object sender, CancelEventArgs e)
        {

            Properties.Settings.Default.Save();
            //Before the program shuts down we make sure that the file is empty
            if( Path != String.Empty)
            {
                try{
                    FileWriter.WriteToFile(Path, string.Empty);
                }
                catch( System.Exception )
                {
                    //Do nothing since the program is shutting down anyway..
                }
            }
            
        }
        #endregion

        #region "Thread events"

        private void SongTimerElapsed(object sender, ElapsedEventArgs e)
        {
            BackgroundWorker bw = new BackgroundWorker();
            bw.DoWork += SongTimerDoWork;
            bw.RunWorkerAsync();
        }
        
        private void SongTimerDoWork(object sender, DoWorkEventArgs e)
        {
            string text = SongUpdater();
            text = MediaPlayerSongReader.Options.ShortenTextOption.PerformTextOption(text);
            
            //Update the label with the currently playing song
            lblCurrentSong.Dispatcher.BeginInvoke(new Action(() => { lblCurrentSong.Content = text; }));
            //Write to file

            FileWriter.WriteToFile(Path, text);
        }

        private void MediaPlayerTimerElapsed(object sender, ElapsedEventArgs e)
        {
            BackgroundWorker bw = new BackgroundWorker();
            bw.DoWork += MediaPlayerTimerDoWork;
            bw.RunWorkerAsync();
        }
        
        private void MediaPlayerTimerDoWork(object sender, DoWorkEventArgs e)
        {
            CheckForRunningMediaPlayers();
            
            lblCurrentSong.Dispatcher.BeginInvoke(
                new Action(() =>
                    {
                        ToggleButton(btnSpotify, _runningSpotify);
                        ToggleButton(btnWinamp, _runningWinAmp);
                    }
                ));
        }
        #endregion

        #region "Menu"
        
        private void miChangeFile_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog fileDialog = new SaveFileDialog();
            
            if (fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                _songTimer.Stop();
                lblCurrentSong.Dispatcher.BeginInvoke(new Action(() => { lblCurrentSong.Content = string.Empty; }));
                SelectedMediaPlayer = null;
                Properties.Settings.Default.FilePath = fileDialog.FileName;
                Path = Properties.Settings.Default.FilePath;
            }
        }

        private void miOptions_Click(object sender, RoutedEventArgs e)
        {
            MediaPlayerSongReader.UserControls.OptionUserControl optionsUserControl = new MediaPlayerSongReader.UserControls.OptionUserControl();

            Window window = new Window();
            window.Content = optionsUserControl;
            window.Title = "Options";
            window.Icon = this.Icon;
            //window.Width = 270;
            //window.Height = 180;
            window.ResizeMode = System.Windows.ResizeMode.NoResize;
            window.SizeToContent = System.Windows.SizeToContent.WidthAndHeight;

            optionsUserControl.Parent = window;
            
            window.ShowDialog();
        }

        private void miAbout_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show( "Created by Bananashell. You can simply find me on twitter @Bananashell" );
        }
        
        #endregion

        #region "Button events"

        private void BtnSpotifyClick(object sender, RoutedEventArgs e)
        {
            MediaPlayerHandler mph = new MediaPlayerHandler();
            Process process = mph.GetAvailableMediaPlayers("spotify").FirstOrDefault();

            lock(_lock){
                if (process != null)
                {
                    Spotify spotify = new Spotify(process);
                    SelectedMediaPlayer = spotify;
                }
            }
            _songTimer.Start();
        }

        private void BtnWinampClick(object sender, RoutedEventArgs e)
        {
            MediaPlayerHandler mph = new MediaPlayerHandler();
            Process process = mph.GetAvailableMediaPlayers("winamp").FirstOrDefault();
            
            lock(_lock){
                if (process != null)
                {
                    WinAmp winAmp = new WinAmp(process);
                    SelectedMediaPlayer = winAmp;
                }
            }
            _songTimer.Start();
        }
        #endregion
#endregion

        private string SongUpdater()
        {
            lock( _lock){
                if ( SelectedMediaPlayer != null )
                {
                    try
                    {
                        string song = SelectedMediaPlayer.GetSongname();

                        return song;
                    }
                    catch (MediaPlayerException)
                    {
                        _songTimer.Stop();
                        SelectedMediaPlayer = null;
                    }
                }
            }

            return string.Empty;
        }
        private void CheckForRunningMediaPlayers()
        {
            _runningSpotify = false;
            _runningWinAmp = false;
            MediaPlayerHandler mph = new MediaPlayerHandler();

            foreach (Process p in mph.GetAvailableMediaPlayers(_availableMediaPlayers.ToList()))
            {
                switch (p.ProcessName.ToLower())
                {
                    case Spotify.ProccessName:
                        _runningSpotify = true;
                        break;
                    case WinAmp.ProccessName:
                        _runningWinAmp = true;
                        break;
                }
            }
        }
        private void ToggleButton(Button button, bool toggle)
        {
            button.IsEnabled = toggle;
            button.Opacity = toggle ? 1 : DefaultOpacity;
        }

    }
}
